package com.plumelog.config;


import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import com.plumelog.core.constant.LogMessageConstant;
import com.plumelog.core.dto.BaseLogMessage;
import com.plumelog.core.dto.RunLogMessage;
import com.plumelog.core.dto.TraceLogMessage;
import com.plumelog.core.util.ThreadPoolUtil;
import com.plumelog.lite.client.InitConfig;
import com.plumelog.lite.client.LogSave;
import com.plumelog.lite.logback.util.LogMessageUtil;

import java.util.concurrent.ThreadPoolExecutor;

public class LiteAppender extends AppenderBase<ILoggingEvent> {
    private static final ThreadPoolExecutor threadPoolExecutor = ThreadPoolUtil.getPool(1,1,1);
    private String appName;
    private String env = "default";
    private String runModel;
    private String expand;
    private String logPath;
    private int maxCount = 100;
    private int logQueueSize = 10000;
    private int threadPoolSize = 1;
    private int keepDay = 30;
    private boolean compressor = false;
    private static boolean init = false;

    public LiteAppender() {
    }

    public int getKeepDay() {
        return this.keepDay;
    }

    public void setKeepDay(int keepDay) {
        this.keepDay = keepDay;
    }

    public int getMaxCount() {
        return this.maxCount;
    }

    public void setMaxCount(int maxCount) {
        this.maxCount = maxCount;
    }

    public int getLogQueueSize() {
        return this.logQueueSize;
    }

    public void setLogQueueSize(int logQueueSize) {
        this.logQueueSize = logQueueSize;
    }

    public int getThreadPoolSize() {
        return this.threadPoolSize;
    }

    public void setThreadPoolSize(int threadPoolSize) {
        this.threadPoolSize = threadPoolSize;
    }

    public boolean isCompressor() {
        return this.compressor;
    }

    public void setCompressor(boolean compressor) {
        this.compressor = compressor;
    }

    public String getlogPath() {
        return this.logPath;
    }

    public void setlogPath(String logPath) {
        this.logPath = logPath;
    }

    public String getAppName() {
        return this.appName;
    }

    public void setAppName(String appName) {
        this.appName = appName;
    }

    public String getEnv() {
        return this.env;
    }

    public void setEnv(String env) {
        this.env = env;
    }

    public String getRunModel() {
        return this.runModel;
    }

    public void setRunModel(String runModel) {
        this.runModel = runModel;
    }

    public String getExpand() {
        return this.expand;
    }

    public void setExpand(String expand) {
        this.expand = expand;
    }

    @Override
    protected void append(ILoggingEvent event) {
        if (event != null) {
            this.send(event);
        }

    }

    protected void send(ILoggingEvent event) {
        BaseLogMessage logMessage = LogMessageUtil.getLogMessage(this.appName, this.env, event);
        if (logMessage instanceof RunLogMessage) {
            if (logMessage != null) {
                if (LogSave.rundataQueue.size() < LogSave.queueSize) {
                    LogSave.rundataQueue.add((RunLogMessage) logMessage);
                } else {
                    try {
                        Thread.sleep(10);
                        send(event);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        } else {
            LogSave.pushTracedataQueue((TraceLogMessage) logMessage);
        }

    }

    @Override
    public void start() {
        super.start();
        LogSave.queueSize = 10;
        if (this.runModel != null) {
            LogMessageConstant.RUN_MODEL = Integer.parseInt(this.runModel);
        }

        InitConfig.keepDays = this.keepDay;
        if (this.expand != null && LogMessageConstant.EXPANDS.contains(this.expand)) {
            LogMessageConstant.EXPAND = this.expand;
        }

        if (!init) {
            LogSave.init(this.logQueueSize, this.logPath);

            int a;
            for (a = 0; a < this.threadPoolSize; ++a) {
                threadPoolExecutor.execute(() -> {
                    LogSave.startRunLog(this.maxCount, this.compressor ? "plume_log_list_compress" : "plume_log_list", this.compressor);
                });
            }

            for (a = 0; a < this.threadPoolSize; ++a) {
                threadPoolExecutor.execute(() -> {
                    LogSave.startTraceLog(this.maxCount, this.compressor ? "plume_trace_list_compress" : "plume_trace_list", this.compressor);
                });
            }

            init = true;
        }

    }
}


